package pers.twf.twfRpc;

import lombok.extern.slf4j.Slf4j;
import pers.twf.twfRpc.config.RegistryConfig;
import pers.twf.twfRpc.config.RpcConfig;
import pers.twf.twfRpc.constant.RpcConstant;
import pers.twf.twfRpc.registry.Registry;
import pers.twf.twfRpc.registry.RegistryFactory;
import pers.twf.twfRpc.utils.ConfigUtils;

/**
 * RPC框架应用
 * 相当于holder，存放项目全局的变量
 * 采用双检锁单例模式实现
 * 获取配置时才调用，属于懒加载
 */
@Slf4j
public class RpcApplication {
    private static volatile RpcConfig rpcConfig;

    /**
     * 支持自己传入配置对象
     * @param newRpcConfig
     */
    public static void init(RpcConfig newRpcConfig){
        rpcConfig = newRpcConfig;
        log.info("rpc init, config = {}",newRpcConfig.toString());
//        注册中心初始化
        RegistryConfig registryConfig = rpcConfig.getRegistryConfig();
        Registry registry = RegistryFactory.getInstance(registryConfig.getRegistry());
        registry.init(registryConfig);
        log.info("registry init ,config = {}",registryConfig);

//        创建并注册 Stutdown Hook，JVM 退出时执行操作
        Runtime.getRuntime().addShutdownHook(new Thread(registry::destroy));
    }

    /**
     * 初始化，默认从配置文件中加载配置
     */
    public static void init(){
        RpcConfig newRpcConfig;
        try {
            newRpcConfig = ConfigUtils.loadConfig(RpcConstant.DEFAULT_CONFIG_PREFIX, RpcConfig.class);
        }catch (Exception e){
            newRpcConfig = new RpcConfig();
        }
        init(newRpcConfig);
    }

    public static RpcConfig getRpcConfig(){
        if(rpcConfig == null){
            synchronized (RpcApplication.class){
                if(rpcConfig == null){
                    init();
                }
            }
        }
        return rpcConfig;
    }
}
